package wsz.rocketMq.service.impl;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import wsz.rocketMq.conf.MqMessage;
import wsz.rocketMq.dao.PhoneDao;
import wsz.rocketMq.entity.ExMessage;
import wsz.rocketMq.entity.Phone;
import wsz.rocketMq.service.PhoneService;
import wsz.rocketMq.util.Constants;

import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

/**
 * @author wsz
 * @date 2022/3/2 10:42
 **/
@Slf4j
@Service
public class PhoneServiceImpl implements PhoneService {

    @Autowired
    private PhoneDao phoneDao;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    public Phone findById(Long id) {
        Optional<Phone> phone = phoneDao.findById(id);
        return phone.isPresent() ? phone.get() : null;
    }

    @Override
    public JSONObject kill(Long id) {
        JSONObject result = new JSONObject();
        result.put("status", false);

        // 1.判断商品
        Phone phone = findById(id);
        if (phone == null) {
            result.put("msg", "秒杀商品不存在");
            return result;
        }

        // 2.查询库存
        Long phoneNumber;
        try {
            String num = redisTemplate.opsForValue().get(Constants.KILL_PHONE_KEY);
            phoneNumber= Long.valueOf(num);
        } catch (NumberFormatException ex) {
            ex.printStackTrace();
            result.put("msg", "秒杀失败");
            return result;
        }

        // 3.判断库存
        if (phoneNumber < 1) {
            result.put("msg", "秒杀已结束");
            return result;
        } else {
            // TODO 非原子性判断库存，交给消费者lua原子操作
//            redisTemplate.opsForValue().set(Constants.KILL_PHONE_KEY, String.valueOf(--phoneNumber));
        }

        // 4.发送异步消息-创建订单
        doSendMessage(id);

        result.put("status", true);
        result.put("msg", "秒杀成功，请及时支付订单");
        return result;
    }

    /**
     * 发送rocketMq消息
     * @param id
     */
    private void doSendMessage(Long id) {
        MqMessage message = new MqMessage();
        message.setId(UUID.randomUUID().toString().replaceAll("-", ""));
        message.setPhoneId(id);
        message.setMsg("订单秒杀成功");
        message.setCreateDate(new Date());

        rocketMQTemplate.asyncSend("topic_phone", message, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                log.info("消息发送成功");
            }

            @Override
            public void onException(Throwable e) {
                // TODO-继续重试、单独处理、走额外流程
                log.info("消息发送失败：{}", e.getMessage());
                ExMessage exMessage = new ExMessage();
            }
        });
    }

    @Override
    public List<Phone> findAll() {
        return phoneDao.findAll();
    }
}
